package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.config.PersonPosition;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.entity.InspectionPlanTask;
import com.ruoyi.system.entity.InspectionPlanTaskDetails;
import com.ruoyi.system.entity.PersonPositionEntity;
import com.ruoyi.system.mapper.InspectionPlanTaskDetailsMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.InspectionPlanTaskService;
import com.ruoyi.system.service.PersonPositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.constraints.Size;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("personPositionService")
public class PersonPositionServiceImpl implements PersonPositionService {

    @Resource
    private InspectionPlanTaskDetailsMapper inspectionPlanTaskDetailsMapper;

    @Resource
    private InspectionPlanTaskService inspectionPlanTaskService;

    @Resource
    private ISysUserService sysUserService;

    @Override
    public Map<String, List<BigDecimal[]>> queryById(Integer id) {
        Map<String, List<BigDecimal[]>> result = new HashMap<>();
        // 查询任务详情
        InspectionPlanTask inspectionPlanTask = inspectionPlanTaskService.queryById(id);
        if (!inspectionPlanTask.getPlanTaskState().equals("已完成")) {
            return result;
        }
        InspectionPlanTaskDetails inspectionPlanTaskDetails = new InspectionPlanTaskDetails();
        inspectionPlanTaskDetails.setPlanTaskId(id);
        List<InspectionPlanTaskDetails> taskDetailsList = inspectionPlanTaskDetailsMapper.queryAllByLimit(inspectionPlanTaskDetails);

        if (CollectionUtils.isEmpty(taskDetailsList)) {
            return result;
        }

        List<String> checkTimes = taskDetailsList.stream().map(InspectionPlanTaskDetails::getCheckTime).collect(Collectors.toList());
        // 获取任务巡检的开始和结束时间
        String start = Collections.min(checkTimes);
        String end = Collections.max(checkTimes);
        Long startTime = null;
        Long endTime = null;
        try {
            startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(start).getTime();
            endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(end).getTime();
        } catch (Exception e) {
            log.error("人员定位：日期转换错误.planId:{},startTime:{},endTime:{}", id, start, end);
            return result;
        }

        Set<String> checkUsers = taskDetailsList.stream().map(InspectionPlanTaskDetails::getCheckUser).collect(Collectors.toSet());

        Set<String> checkNicks = new HashSet<>();
        if (CollectionUtils.isEmpty(checkUsers)) {
            return result;
        } else {
            for (String checkUser : checkUsers) {
                String nickName = sysUserService.selectUserByUserName(checkUser).getNickName();
                checkNicks.add(nickName);
            }
        }
        if (CollUtil.isEmpty(checkNicks)) {
            return result;
        }
        // 查所有人员接口
        cn.hutool.json.JSONObject staffList = PersonPosition.dataList();
        staffList.set("checkNicks",checkNicks);
        //获取任务的人员列表<username, tagId>
        Map<String, String> staffTagIdMap = getStaffTagMap(staffList);
        if (CollectionUtils.isEmpty(staffTagIdMap)) {
            return result;
        }

        // 获取人员位置
        result = getUserGIS(staffTagIdMap, startTime, endTime);

        log.info("----------result:{}", JSONUtil.toJsonStr(result));
        return result;
    }

    private Map<String, List<BigDecimal[]>> getUserGIS(Map<String, String> staffTagIdMap, Long startTime, Long endTime) {
        Map<String, List<BigDecimal[]>> result = new HashMap<>();

        for (String username : staffTagIdMap.keySet()) {
            String tagId = staffTagIdMap.get(username);
            if (StringUtils.isBlank(tagId)) {
                continue;
            }
            List<BigDecimal[]> personPositions = new ArrayList<>();

            // 获取人员位置
            List<PersonPositionEntity>  positionResult = getUserPositions(tagId, startTime, endTime);
            if (!CollectionUtils.isEmpty(positionResult)) {
                positionResult.stream().forEach(obj -> {
                   BigDecimal[] dict = new BigDecimal[2];
                   dict[0] = changeX(obj.getX(), obj.getY());
                   dict[1] = changeY(obj.getY(), obj.getY());

                    personPositions.add(dict);
                });

                result.put(username, personPositions);
            }
        }
        return result;
    }

    private List<PersonPositionEntity> getUserPositions(String tagId, Long startTime, Long endTime) {
        log.info("--------获取人员历史轨迹 开始----------tagId:{}, start:{}, end:{}", tagId, startTime, endTime);
        List<PersonPositionEntity> positionList = new ArrayList<>();
        //获取任务的人员列表
        if (StringUtils.isEmpty(tagId)) {
            return positionList;
        }


        cn.hutool.json.JSONObject param = new cn.hutool.json.JSONObject();
        param.set("tagId",tagId);
        param.set("startTime",startTime);
        param.set("endTime",endTime);
        // 查询人员轨迹
        JSONArray records = PersonPosition.findHistory(param);
        if (records != null) {
            List<PersonPositionEntity> list = JSONUtil.toList(records, PersonPositionEntity.class);
            positionList.addAll(list);
        }
        log.info("--------获取人员历史轨迹 结束----------{}", tagId);

        return positionList;
    }

    private  BigDecimal changeX(Double x, Double y) {
        double a = 1.179935d, b = -0.036857d, c = 13513410.585426d;
        BigDecimal lat = new BigDecimal(0.0);
        if (x != null || y != null) {
            lat = new BigDecimal(a).multiply(new BigDecimal(x)).add(new BigDecimal(b).multiply(new BigDecimal(y))).add(new BigDecimal(c)).setScale(5, BigDecimal.ROUND_UP);
        }
        return lat;
    }
    private  BigDecimal changeY(Double x, Double y) {
        double d = -0.043495, e = 1.188015, f = 3693655.268790;
        BigDecimal lon = new BigDecimal(0);
        if (x != null || y != null) {
            lon = new BigDecimal(e).multiply(new BigDecimal(x)).add(new BigDecimal(d).multiply(new BigDecimal(y))).add(new BigDecimal(f)).setScale(5, BigDecimal.ROUND_UP);
        }
        return lon;
    }

    //调用第三方接口返回所有员工信息（Map<name,tagId>）
    private Map<String, String> getStaffTagMap(cn.hutool.json.JSONObject jsonObject) {
        Map<String, String> map = new HashMap<>();
        if (jsonObject == null || !jsonObject.containsKey("data")) {
            return map;
        }
        cn.hutool.json.JSONObject data = (cn.hutool.json.JSONObject) jsonObject.get("data");
        if (data == null || !data.containsKey("records")) {
            return map;
        }
        JSONArray records = (JSONArray) data.get("records");
        JSONArray checkNicks = jsonObject.getJSONArray("checkNicks");
        if (records.size() > 0) {
            for (int i = 0; i < records.size(); i++) {
                if (Objects.isNull(records.get(i))) {
                    continue;
                }
                cn.hutool.json.JSONObject staffInfo = (cn.hutool.json.JSONObject) records.get(i);
                String name = staffInfo.getStr("name");
                String tagId = staffInfo.getStr("tagId");
                boolean contains = checkNicks.contains(name);
                if (contains) {
                    map.put(name, tagId);
                }
                //log.info("name:{},tagId:{}", name, tagId);
            }
        }
        log.info("------userTagMap:{}", map);

        return map;
    }


}
